package com.bayihouse.service.impl;


import cn.hutool.http.ContentType;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bayihouse.common.ErrorCode;
import com.bayihouse.exception.BusinessException;
import com.bayihouse.mapper.FileInfoMapper;
import com.bayihouse.model.entity.FileInfo;
import com.bayihouse.model.request.file.FileSearchRequest;
import com.bayihouse.model.vo.FileVO;
import com.bayihouse.service.AdministerService;
import com.bayihouse.service.FileInfoService;
import com.bayihouse.utils.MinioUtils;
import com.google.common.net.HttpHeaders;
import io.minio.GetObjectResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.util.IOUtils;
import org.springframework.http.ContentDisposition;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

/**
 * @author Administrator
 * @description 针对表【fileinfo】的数据库操作Service实现
 * @createDate 2024-12-27 14:02:14
 */
@Service
@Slf4j
public class FileInfoServiceImpl extends ServiceImpl<FileInfoMapper, FileInfo> implements FileInfoService {
    @Resource
    private MinioUtils minioService;

    @Resource
    private AdministerService administerService;

    @Override
    public FileVO upload(MultipartFile multipartFile, String parentPath, String detail, String type, HttpServletRequest request) throws Exception {
        if (multipartFile.isEmpty()) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "文件上传失败,网络问题");
        }
        Long userId = administerService.getLoginAdminister(request).getId();
        String objectName = minioService.uploadObject(multipartFile, userId, parentPath);
        boolean objectExist = minioService.isObjectExist(objectName);
        FileInfo fileInfo = new FileInfo();
        if (objectExist) {
            fileInfo.setFileName(objectName);
            fileInfo.setUserId(userId);
            fileInfo.setDetail(detail);
            fileInfo.setType(type);
            fileInfo.setSize(multipartFile.getSize());
            boolean save = this.save(fileInfo);
        }
        FileVO fileVO = new FileVO();
        fileVO.setFileUrl(minioService.getUrl(objectName));
        fileVO.setId(fileInfo.getId());
        int i = objectName.lastIndexOf("//");
        fileVO.setFileName(objectName.substring(i + 2));
        return fileVO;
    }

    @Override
    public boolean download(FileInfo fileInfo, HttpServletResponse response) {
        try {
            GetObjectResponse outResponse = minioService.getObject(fileInfo.getFileName());
            // 获取文件后缀名
            log.info("文件名为:" + fileInfo.getFileName());
            // 清空response
            response.reset();
            // 文件类型
            response.setContentType(ContentType.OCTET_STREAM.getValue());
            // 文本类型文件的编码
            response.setCharacterEncoding(StandardCharsets.UTF_8.displayName());
            // 文件长度
            response.setContentLength(Math.toIntExact(fileInfo.getSize()));
            // 文件的处理方式。attachment 表示附件，filename 表示文件的名称
            response.setHeader(HttpHeaders.CONTENT_DISPOSITION, ContentDisposition.attachment()    // 附件形式
                    .filename(fileInfo.getFileName(), StandardCharsets.UTF_8)  // 文件名称 & 编码
                    .build().toString());
            IOUtils.copy(outResponse, response.getOutputStream());
            response.getOutputStream().flush();
        } catch (Exception ex) {
            System.out.println(ex.getMessage());
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "文件操作异常");
        }
        return true;
    }


    @Override
    public Wrapper<FileInfo> getQueryWrapper(FileSearchRequest fileSearchRequest) {
        Long id = fileSearchRequest.getId();
        Long userId = fileSearchRequest.getUserId();
        int minSize = fileSearchRequest.getMinSize();
        int maxSize = fileSearchRequest.getMaxSize();
        String fileName = fileSearchRequest.getFileName();
        String detail = fileSearchRequest.getDetail();
        QueryWrapper<FileInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(id != null, "id", id);
        queryWrapper.eq(userId != null, "userid", userId);
        queryWrapper.between(minSize != 0, "size", minSize, maxSize);
        queryWrapper.like(StringUtils.isNotBlank(fileName), "filename", fileName);
        queryWrapper.like(StringUtils.isNotBlank(detail), "detail", detail);
        return queryWrapper;
    }

    @Override
    public List<String> getDisplayUrls(List<Long> displayIds) {
        List<FileInfo> fileInfoList = this.listByIds(displayIds);
        List<String> displayUrls = new ArrayList<>();
        fileInfoList.stream().forEach(fileInfo -> {
            try {
                String url = minioService.getUrl(fileInfo.getFileName());
                displayUrls.add(url);
            } catch (Exception e) {
                throw new BusinessException(ErrorCode.OPERATION_ERROR, "文件操作异常");
            }
        });
        return displayUrls;
    }
}




